# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# The python packages install into a versioned dir.  We have to force
# a rebuild of them all.

set -e

OLD_PY_VER="2.6"
NEW_PY_VER="2.7"

export CLEAN_DELAY=0

find_pkgs() {
  (

  # Find pkgs which install .py files into versioned dirs.
  ${qfile} -CRq "${root}"/usr/{,local/}lib*/python${OLD_PY_VER}

  # Find pkgs which link against libpython2.6.so.
  sudo scanelf -F'#N%F' -qyR -N libpython${OLD_PY_VER}.so.1.0 \
    "${root}"/{{,usr/}{opt,lib*,*bin},usr/local} | \
    xargs -r ${qfile} -CRq

  ) | sort -u
}

update_python() {
  # Force upgrade to python-2.7 from python-2.6.
  if portageq has_version ${root} "dev-lang/python:${OLD_PY_VER}"; then
    info "${board}: cleaning out dev-lang/python-${OLD_PY_VER}"
    sudo ${emerge} -qC "dev-lang/python:${OLD_PY_VER}"
    sudo ${emerge} -q1ug "dev-lang/python:${NEW_PY_VER}"
  fi
}

update_pkgs() {
  # Try and update/rebuild any packages.
  info "${board}: searching for packages using python-${OLD_PY_VER}"
  local pkgs=( $(find_pkgs) )
  if [[ ${#pkgs[*]} -gt 0 ]]; then
    info "${board}: cleaning out packages"
    sudo ${emerge} -qC "${pkgs[@]}"
    if cd "${root}/packages" 2>/dev/null; then
      sudo rm -f ${pkgs[@]/%/-*.tbz2}
    fi

    # Note: we allow this stage to fail because the binpkgs might be old
    # and relying on python-2.6.  Since we nuked that version though, most
    # will fail to even emerge.
    info "${board}: trying to update via binpkgs"
    if ! sudo ${emerge} -q1ug "${pkgs[@]}"; then
      sudo ${emerge} -q1u "${pkgs[@]}" || :
    fi

    pkgs=( $(find_pkgs) )
    if [[ ${#pkgs[*]} -gt 0 ]]; then
      info "${board}: forcing rebuild from source"
      sudo ${emerge} -q1 "${pkgs[@]}"
    fi
  fi

  sudo rm -rf --one-file-system "${root}"/usr/{,local/}lib*/python${OLD_PY_VER}
}

b() {
  local cmd=$1 root=$2 board=$3
  local emerge="/mnt/host/source/chromite/bin/parallel_emerge"
  local qfile="qfile"
  if [[ ${root} != "/" ]]; then
    emerge+=" --board=${board}"
    qfile+="-${board}"
  fi
  "$@"
}

update_sdk() {
  info "Updating python in host sdk"

  # First we install python-2.7.
  sudo ${emerge} -q1ug "dev-lang/python:${NEW_PY_VER}"

  # Then we try to install as many binpkgs as we can.
  local pkgs=( $(find_pkgs) )
  sudo ${emerge} -q1g "${pkgs[@]}" || :

  # Then we fallback to the python cleaner logic to do everything.
  "${SCRIPTS_DIR}/python_cleaner"
}

# Update host sdk first before we update the boards.  We have to
# do this specially since the package manager is based on python.
b update_sdk / host_sdk

# Update board python in parallel.
for board_root in /build/*; do
  board=${board_root##*/}
  b update_python ${board_root} ${board} &
done
wait

# Update board packages in serial (might build from source).
for board_root in /build/*; do
  board=${board_root##*/}
  b update_pkgs ${board_root} ${board}
done

wait
